package com.dzt.androidframework.gesture;

import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.view.Display;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.widget.ImageView;

import com.dzt.androidframework.R;
import com.dzt.androidframework.activity.ActivityTitle;
import com.dzt.androidframework.gesture.lib.MoveGestureDetector;
import com.dzt.androidframework.gesture.lib.RotateGestureDetector;
import com.dzt.androidframework.gesture.lib.ShoveGestureDetector;

public class GestureActivity extends ActivityTitle implements View.OnTouchListener {
	private Matrix mMatrix = new Matrix();
	private float mScaleFactor = .4f;
	private float mRotationDegrees = 0.f;
	private float mFocusX = 0.f;
	private float mFocusY = 0.f;
	private int mAlpha = 255;
	private int mImageHeight, mImageWidth;

	private ScaleGestureDetector mScaleDetector;
	private RotateGestureDetector mRotateDetector;
	private MoveGestureDetector mMoveDetector;
	private ShoveGestureDetector mShoveDetector;

	@Override
	protected int getLayoutId() {
		return R.layout.activity_gesture;
	}

	@Override
	protected void initParams() {
		setTitleView(R.string.menu_6);
		// Determine the center of the screen to center 'earth'
		Display display = getWindowManager().getDefaultDisplay();
		mFocusX = display.getWidth() / 2f;
		mFocusY = display.getHeight() / 2f;

		// Set this class as touchListener to the ImageView
		ImageView view = (ImageView) findViewById(R.id.imageView);
		view.setOnTouchListener(this);

		// Determine dimensions of 'earth' image
		Drawable d = ContextCompat.getDrawable(this, R.mipmap.earth);
		mImageHeight = d.getIntrinsicHeight();
		mImageWidth = d.getIntrinsicWidth();

		// View is scaled and translated by matrix, so scale and translate initially
		float scaledImageCenterX = (mImageWidth * mScaleFactor) / 2;
		float scaledImageCenterY = (mImageHeight * mScaleFactor) / 2;

		mMatrix.postScale(mScaleFactor, mScaleFactor);
		mMatrix.postTranslate(mFocusX - scaledImageCenterX, mFocusY - scaledImageCenterY);
		view.setImageMatrix(mMatrix);

		// Setup Gesture Detectors
		mScaleDetector = new ScaleGestureDetector(getApplicationContext(), new ScaleListener());
		mRotateDetector = new RotateGestureDetector(getApplicationContext(), new RotateListener());
		mMoveDetector = new MoveGestureDetector(getApplicationContext(), new MoveListener());
		mShoveDetector = new ShoveGestureDetector(getApplicationContext(), new ShoveListener());
	}

	@Override
	protected void initData(Bundle savedInstanceState) {

	}

	@Override
	protected String[] initPermissions() {
		return new String[0];
	}

	@Override
	public boolean onTouch(View v, MotionEvent motionEvent) {
		mScaleDetector.onTouchEvent(motionEvent);
		mRotateDetector.onTouchEvent(motionEvent);
		mMoveDetector.onTouchEvent(motionEvent);
		mShoveDetector.onTouchEvent(motionEvent);

		float scaledImageCenterX = (mImageWidth * mScaleFactor) / 2;
		float scaledImageCenterY = (mImageHeight * mScaleFactor) / 2;

		mMatrix.reset();
		mMatrix.postScale(mScaleFactor, mScaleFactor);
		mMatrix.postRotate(mRotationDegrees, scaledImageCenterX, scaledImageCenterY);
		mMatrix.postTranslate(mFocusX - scaledImageCenterX, mFocusY - scaledImageCenterY);

		ImageView view = (ImageView) v;
		view.setImageMatrix(mMatrix);
		view.setAlpha(mAlpha);

		return true; // indicate event was handled
	}

	private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
		@Override
		public boolean onScale(ScaleGestureDetector detector) {
			mScaleFactor *= detector.getScaleFactor(); // scale change since previous event

			// Don't let the object get too small or too large.
			mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f));

			return true;
		}
	}

	private class RotateListener extends RotateGestureDetector.SimpleOnRotateGestureListener {
		@Override
		public boolean onRotate(RotateGestureDetector detector) {
			mRotationDegrees -= detector.getRotationDegreesDelta();
			return true;
		}
	}

	private class MoveListener extends MoveGestureDetector.SimpleOnMoveGestureListener {
		@Override
		public boolean onMove(MoveGestureDetector detector) {
			PointF d = detector.getFocusDelta();
			mFocusX += d.x;
			mFocusY += d.y;
			return true;
		}
	}

	private class ShoveListener extends ShoveGestureDetector.SimpleOnShoveGestureListener {
		@Override
		public boolean onShove(ShoveGestureDetector detector) {
			mAlpha += detector.getShovePixelsDelta();
			if (mAlpha > 255)
				mAlpha = 255;
			else if (mAlpha < 0)
				mAlpha = 0;

			return true;
		}
	}
}
